package com.topisv.tms.web.work;

import static com.google.common.base.Preconditions.checkArgument;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.UUID;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveAction;
import java.util.concurrent.TimeUnit;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;

import jxl.Workbook;
import jxl.write.Label;
import jxl.write.WritableSheet;
import jxl.write.WritableWorkbook;
import jxl.write.WriteException;
import jxl.write.biff.RowsExceededException;
import net.sf.json.JSONObject;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.session.Session;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springside.modules.web.Servlets;

import com.fasterxml.jackson.core.JsonGenerationException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.topisv.tms.costants.Constants;
import com.topisv.tms.entity.AreaGroup;
import com.topisv.tms.entity.CustomerLead;
import com.topisv.tms.entity.Customers;
import com.topisv.tms.entity.EdiOrder;
import com.topisv.tms.entity.EdiOrderItem;
import com.topisv.tms.entity.JSONParam;
import com.topisv.tms.entity.LogisticsCompany;
import com.topisv.tms.entity.ShopSource;
import com.topisv.tms.entity.ediOrder.VEdiOrder;
import com.topisv.tms.entity.ediOrder.VEdiOrderItem;
import com.topisv.tms.entity.work.WholePileConfig;
import com.topisv.tms.entity.work.WorkBatch;
import com.topisv.tms.entity.work.WorkOrder;
import com.topisv.tms.entity.work.WorkOrderNoCascade;
import com.topisv.tms.entity.work.WorkTask;
import com.topisv.tms.entity.work.WorkTaskItem;
import com.topisv.tms.rest.entity.Batch;
import com.topisv.tms.rest.entity.Box;
import com.topisv.tms.rest.entity.Box_detail;
import com.topisv.tms.rest.entity.Order;
import com.topisv.tms.service.AreaGroupService;
import com.topisv.tms.service.CustomerLeadService;
import com.topisv.tms.service.CustomersService;
import com.topisv.tms.service.EdiOrderService;
import com.topisv.tms.service.LogisticsCompanyService;
import com.topisv.tms.service.ShopSourceService;
import com.topisv.tms.service.account.ShiroDbRealm.ShiroUser;
import com.topisv.tms.service.ediOrder.VEdiOrderItemService;
import com.topisv.tms.service.ediOrder.VEdiOrderService;
import com.topisv.tms.service.work.WholePileConfigService;
import com.topisv.tms.service.work.WorkBatchService;
import com.topisv.tms.service.work.WorkOrderService;
import com.topisv.tms.service.work.WorkTaskItemService;
import com.topisv.tms.service.work.WorkTaskService;
import com.topisv.tms.tools.DataTablesUtils;
import com.topisv.tms.tools.ExcelStUtil;
import com.topisv.tms.tools.ExcelUtils;
import com.topisv.tms.tools.TablePojo;
import com.topisv.tms.utils.DateUtils;
import com.topisv.tms.utils.InitProperties;
import com.topisv.tms.utils.SystemUtil;
import com.topisv.tms.utils.TimeUtil;
import com.topisv.tms.utils.enums.StatusEnums;
import com.topisv.tms.utils.http.HttpPost;
import com.topisv.tms.web.base.BaseController;

/**
 * 作业批次_control
 * 
 * @author ch
 */
@Controller
@RequestMapping({"/workBatch"})
public class WorkBatchController extends BaseController {
    
    private Logger LOG = LoggerFactory.getLogger(WorkBatchController.class);
    
    @Autowired
    private EdiOrderService ediOrderService;
    
    @Autowired
    private WorkBatchService workBatchService;	
    
    @Autowired
    private WorkTaskService workTaskService;
    
    @Autowired
    private WorkTaskItemService workTaskItemService;
    
    @Autowired
    private WorkOrderService workOrderService;
    
    @Autowired
    private CustomersService customersService;
    
    @Autowired
    private AreaGroupService areaGroupService;
    
    @Autowired
    private ShopSourceService ShopSourceService;
    
    @Autowired
    private LogisticsCompanyService logisticsCompanyService;
    
    @Autowired
    private WholePileConfigService wpcService;
    
    @Autowired
    private CustomerLeadService customerLeadService;
    
    
    @Autowired
    private VEdiOrderService vEdiOrderService;
    
    @Autowired
    private VEdiOrderItemService vEdiOrderItemService;
    
    /**
     * 导向待处理订单页面
     * 
     * @param model
     * @param request
     * @return
     */
    @RequestMapping(value = "v2_unhandleOrderAssignCompanyPage")
    public String unhandleOrderAssignCompanyPage(Model model, ServletRequest request) {
        try {
            
            // 查出当前用户关联的商家列表
            ShiroUser curUser = (ShiroUser)SecurityUtils.getSubject().getPrincipal();
            List<Customers> customerList = this.customersService.loadCustomerByAuthority(curUser);
            model.addAttribute("customerList", customerList);
            model.addAttribute("userType", curUser.userType);
            
            // 快递公司
            List<LogisticsCompany> cmpList = this.logisticsCompanyService.findAll();
            model.addAttribute("cmpList", cmpList);
            
            List<EdiOrder> orderList = new ArrayList<EdiOrder>();
            model.addAttribute("orderList", orderList);
            
            model.addAttribute("tab1", "active");
            
        } catch (Exception e) {
            
            log.error("error", e);
        }
        return "work/createTask/unhandleOrderAssignCompany";
    }
    
    /**
     * 导向待处理订单页面
     * 
     * @param model
     * @param request
     * @return
     */
    @RequestMapping(value = "v2_toUnhandleOrderPage")
    public String toUnhandleOrderPage(Model model, ServletRequest request) {
        try {
            
            // 查出当前用户关联的商家列表
            ShiroUser curUser = (ShiroUser)SecurityUtils.getSubject().getPrincipal();
            List<Customers> customerList = this.customersService.loadCustomerByAuthority(curUser);
            model.addAttribute("customerList", customerList);
            model.addAttribute("userType", curUser.userType);
            
            // 快递公司
            List<LogisticsCompany> cmpList = this.logisticsCompanyService.findAll();
            model.addAttribute("cmpList", cmpList);
            
            // 如果是商家用户,初始化数据
            if ("customer".equals(curUser.userType)) {
                
                String customerCode = curUser.customerCode;
                model.addAttribute("customerCode", customerCode);
                
                // 初始化商家店铺
                List<ShopSource> shopList = this.ShopSourceService.findByCustomerCode(customerCode);
                model.addAttribute("shopList", shopList);
                
                // 初始化仓库数据
                List<AreaGroup> warehouseList = this.areaGroupService.loadAreaGroupByAuthority(curUser, customerCode);
                model.addAttribute("warehouseList", warehouseList);
                
                // 查询未处理订单，并区分单件、多件 (默认使用SKU优先策略：skufirst)
                Map<String, Object> param = new HashMap<String, Object>();
                param.put("customerCode", customerCode);
                param.put("orderStatus", "ok");
                param.put("status", "pending");
                param.put("psFlag", "0");
                Map<String, List<EdiOrder>> orderMap = this.ediOrderService.loadUnhandledOrder(param, "skufirst");
                List<EdiOrder> singleList = orderMap.get("single");
                List<EdiOrder> multiList = orderMap.get("multi");
                model.addAttribute("singleList", singleList);
                model.addAttribute("multiList", multiList);
            }
            
            model.addAttribute("tab1", "active");
            
        } catch (Exception e) {
            
            log.error("error", e);
        }
        return "work/createTask/unhandleOrder";
    }
    
    /**
     * 查询待处理订单数据
     * 
     * @param model
     * @param request
     * @param response
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "v2_query", method = RequestMethod.POST)
    public String query(Model model, ServletRequest request, ServletResponse response)
        throws Exception
    {
        String returnUrl = "work/createTask/unhandleOrder";
        try {
            // 查出当前用户关联的商家列表
            ShiroUser curUser = (ShiroUser)SecurityUtils.getSubject().getPrincipal();
            List<Customers> customerList = this.customersService.loadCustomerByAuthority(curUser);
            model.addAttribute("customerList", customerList);
            model.addAttribute("userType", curUser.userType);
            
            // 快递公司
            List<LogisticsCompany> cmpList = this.logisticsCompanyService.findAll();
            model.addAttribute("cmpList", cmpList);
            
            // 查询未处理订单，并区分单件、多件 (默认使用sku优先策略：skufirst)
            Map<String, Object> searchParams = Servlets.getParametersStartingWith(request, "_");
            String tacticsType = (String)searchParams.get("tacticsType");
            String fromDateStr = (String)searchParams.get("fromDate");
            String toDateStr = (String)searchParams.get("toDate");
            String customerCode = (String)searchParams.get("customerCode");
            String warehouseCode = (String)searchParams.get("warehouseCode");
            String companyCode = (String)searchParams.get("companyCode");
            String outScope = (String)searchParams.get("outScope");
            String mergeOrder = (String)searchParams.get("mergeOrder");
            
            String minWeight = (String)searchParams.get("minWeight");
            String maxWeight = (String)searchParams.get("maxWeight");
            
            String psFlag = (String)searchParams.get("psFlag");//优先派送标志
            
            String remark = (String)searchParams.get("remark");//是否有备注
            
            if ("true".equals(mergeOrder)) {
                returnUrl = "work/createTask/unhandleOrderAssignCompany";
            }
            String scopeFilter = (String)searchParams.get("scopeFilter");
            String isInvoice = (String)searchParams.get("isInvoice");
            String psCompanyCode = (String)searchParams.get("psCompanyCode");
            //add 当前已指定快递  20160725 bug:439
            String psCurrentCompanyCode = (String) searchParams.get("psCurrentCompanyCode");
            
            String lockOutScopeOrdernoStr = (String)searchParams.get("lockOutScopeOrdernoStr");
            String isLockOutScopeOrderno = (String)searchParams.get("lockOutScopeOrderno");
            
            //add 添加单据号查询条件 bug 0000452
            String documentno = (String) searchParams.get("documentno");
            
            Date fromDate = null;
            Date toDate = null;
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            if (StringUtils.isNotEmpty(fromDateStr)) {
                //fromDate = sdf.parse(fromDateStr + " 00:00:00");
                fromDate = sdf.parse(fromDateStr + ":00");
            }
            if (StringUtils.isNotEmpty(toDateStr)) {
                //toDate = sdf.parse(toDateStr + " 23:59:59");
                toDate = sdf.parse(toDateStr + ":59");
            }
            
            searchParams.put("minWeight", minWeight);
            searchParams.put("maxWeight", maxWeight);
            searchParams.put("companyCode", companyCode);
            searchParams.put("lockOutScopeOrdernoStr", lockOutScopeOrdernoStr);
            searchParams.put("isLockOutScopeOrderno", isLockOutScopeOrderno);
            
            searchParams.put("customerCode", customerCode);
            searchParams.put("psCompanyCode", psCompanyCode);
            //add 当前已指定快递  20160725 bug:439
            searchParams.put("psCurrentCompanyCode", psCurrentCompanyCode);
            
            if (StringUtils.isEmpty(warehouseCode)) { // 如果仓库编码为空，赋予默认权限值
                String areagroups = getShiroUser().areagroups;
                searchParams.put("areagroups", areagroups);
            } else {
                searchParams.put("warehouseCode", warehouseCode);
            }
            
            searchParams.put("mergeOrder", mergeOrder);
            searchParams.put("fromDate", fromDate);
            searchParams.put("toDate", toDate);
            searchParams.put("orderStatus", "ok");
            searchParams.put("status", "pending");
            searchParams.put("dispatchFlag", "1");
            searchParams.put("outScope", outScope);
            searchParams.put("scopeFilter", scopeFilter);
            searchParams.put("isInvoice", isInvoice);
            searchParams.put("documentno", documentno);
            searchParams.put("psFlag", psFlag);
            searchParams.put("remark", remark);
            
            // Map<String, List<EdiOrder>> orderMap = this.ediOrderService.loadUnhandledOrder(searchParams,tacticsType);
            Map<String, List<EdiOrder>> orderMap = this.ediOrderService.loadUnhandledOrderNew(searchParams, tacticsType);
            //change by huwenjun 检索并排除结果中未设置区域等级的数据 begin
            //创建订单列表的临时变量
            List<EdiOrder> tmp_allOrderList = orderMap.get("allOrderList");
            List<EdiOrder> tmp_singleList = orderMap.get("single");
            List<EdiOrder> tmp_multiList = orderMap.get("multi");
            //订单列表变量
            List<EdiOrder> allOrderList = new ArrayList<EdiOrder>();
            List<EdiOrder> singleList = new ArrayList<EdiOrder>();
            List<EdiOrder> multiList = new ArrayList<EdiOrder>();
            //所有结果数量
            int totalListCount = 0;
            if("true".equals(mergeOrder)){
            	totalListCount = tmp_allOrderList.size(); 
            } else {
            	totalListCount = tmp_singleList.size();
            	totalListCount += tmp_multiList.size();
            }
            //区域等级未处理完的数量
            int isHaveNotSetRegionalLevel = 0;
            if("true".equals(mergeOrder)){
            	for(EdiOrder eo : tmp_allOrderList) {
					if(eo.getRegionalLevel() == null) {
						isHaveNotSetRegionalLevel += 1;
					}
					if(eo.getRegionalLevel() != null) {
						if(scopeFilter.equals(eo.getRegionalLevel().toString()))
							allOrderList.add(eo);
					}
				}
            } else {
            	for(EdiOrder eo : tmp_singleList) {
					if(eo.getRegionalLevel() == null) {
						isHaveNotSetRegionalLevel += 1;
					} 
					if(eo.getRegionalLevel() != null) {
						if(scopeFilter.equals(eo.getRegionalLevel().toString()))
							singleList.add(eo);
					}
				}
            	for(EdiOrder eo : tmp_multiList) {
					if(eo.getRegionalLevel() == null) {
						isHaveNotSetRegionalLevel += 1;
					} 
					if(eo.getRegionalLevel() != null) {
						if(scopeFilter.equals(eo.getRegionalLevel().toString()))
							multiList.add(eo);
					}
				}
            }
            tmp_allOrderList = null;
            tmp_singleList = null;
            tmp_multiList = null;
            model.addAttribute("totalListCount", totalListCount);
            model.addAttribute("isHaveNotSetRegionalLevel", isHaveNotSetRegionalLevel);
            //end
            
            if (!"on".equals(isLockOutScopeOrderno)) {
                lockOutScopeOrdernoStr = "";
            }
            model.addAttribute("lockOutScopeOrdernoStr", lockOutScopeOrdernoStr);
            model.addAttribute("isLockOutScopeOrderno", isLockOutScopeOrderno);
            
            model.addAttribute("allOrderList", allOrderList);
            model.addAttribute("singleList", singleList);
            model.addAttribute("multiList", multiList);
            model.addAttribute("customerCode", customerCode);
            model.addAttribute("warehouseCode", warehouseCode);
            model.addAttribute("companyCode", companyCode);
            model.addAttribute("psCompanyCode", psCompanyCode);
            
            model.addAttribute("psCompanyCode", psCompanyCode);
            model.addAttribute("psCompanyCode", psCompanyCode);
            
            model.addAttribute("psFlag", psFlag);
            
            model.addAttribute("remark", remark);
            
            model.addAttribute("tab1", "active");
            
            // 获取整托配置
            List<WholePileConfig> wpcList = wpcService.findAllConfig();
            model.addAttribute("wpcList", wpcList);
            
            // 初始化商家店铺
            List<ShopSource> shopList = this.ShopSourceService.findByCustomerCode(customerCode);
            model.addAttribute("shopList", shopList);
            
            // 初始化仓库数据
            List<AreaGroup> warehouseList = this.areaGroupService.loadAreaGroupByAuthority(curUser, customerCode);
            model.addAttribute("warehouseList", warehouseList);
        } catch (Exception e) {
            log.error("error", e);
        }
        
        return returnUrl;
    }
    
    /**
     * 
     * 标记为优先派送
     *
     * @param ordernos
     * @param request
     * @param response [参数说明]
     * @author <a href=mailto:zhangweize@nryuncang.com>zhangweize</a>
     * @version 1.0.0
     */
	@RequestMapping(value = "signPriorSend")
	public void signPriorSend(@RequestParam(value = "ordernos") String[] ordernos, ServletRequest request, HttpServletResponse response) {
		JSONObject json = null;
		PrintWriter out = null;
		int successCount = 0;
		try {
			out = response.getWriter();
			json = new JSONObject();

			// 判断订单数组的长度是否为0，为0，返回结果
			if (ordernos.length == 0) {
				json.put("status", "0");
				json.put("msg", "请选择订单!");
				return;
			}
			
			for (String orderno : ordernos){
				successCount = workBatchService.signPriorSend(orderno) == true ?  (++successCount) : successCount;
			}
			
			json.put("status", "1");
		    json.put("msg", "成功，共" + ordernos.length + "单,标记成功" + successCount + "单,失败" + (ordernos.length - successCount)+"单");

		} catch (Exception e) {
			log.error("{}标记为优先派送失败:{}", ordernos, e );
			json.put("status", "0");
			json.put("msg", "标记为优先派送失败，共" + ordernos.length + "单,标记成功" + successCount + "单" );

		} finally {
			out.print(json.toString());
		}
	}
    
    
    /**
     * ajax创建作业批次
     * 
     * @param request
     * @param response
     * @return
     */
    @RequestMapping(value = "assignCompany")
    @ResponseBody
    public void assignCompany(ServletRequest request, HttpServletResponse response) {
        JSONObject json = null;
        PrintWriter out = null;
        try {
            out = response.getWriter();
            json = new JSONObject();
            
            String selectedOrder = request.getParameter("selectedOrder");
            String psCompanyCode = request.getParameter("psCompanyCode");
            if (StringUtils.isEmpty(selectedOrder)) {
                return;
            }
            this.workBatchService.assignCompany(selectedOrder, psCompanyCode);
            
            json.put("status", "success");
            out.print(json.toString());
        } catch (Exception e) {
            log.error("assignCompany error.", e);
            json.put("status", "fail");
            json.put("content", "系统异常,请联系管理员!");
            out.print(json.toString());
        }
    }
    
    /**
     * ajax创建作业批次
     * 
     * @param request
     * @param response
     * @return
     */
    @RequestMapping(value = "ajaxCreateWorkBatch")
    @ResponseBody
    public String ajaxCreateWorkBatch(ServletRequest request, HttpServletResponse response) {
        String flag = "false";
        long tempT = System.currentTimeMillis();
        try {
            
            String tacticsType = request.getParameter("tacticsType");
            Integer orderNum = Integer.valueOf(request.getParameter("orderNum"));
            String customerCode = request.getParameter("customerCode");
            String warehouseCode = request.getParameter("warehouseCode");
            String companyCode = request.getParameter("companyCode");
            // String seCompanyCode=request.getParameter("seCompanyCode");
            String psCompanyCode = request.getParameter("psCompanyCode");
            
            String billType = request.getParameter("billType");
            String pickType = request.getParameter("pickType");
            String flowType = request.getParameter("flowType");
            String orders = request.getParameter("orders");
            
            //优先派送标志
            String psFlag = request.getParameter("psFlag");
            
            String[] ordersArray = orders.split("【P】");
            if ("QRT".equals(companyCode)) {
                companyCode = "";
            }
            // if("-2".equals(seCompanyCode)&&!StringUtils.isEmpty(psCompanyCode)){
            companyCode = psCompanyCode;
            // }
            this.workBatchService.createWorkBatch(tacticsType,
                orderNum,
                customerCode,
                companyCode,
                warehouseCode,
                ordersArray,
                pickType,
                billType,
                flowType,
                psFlag);
            flag = "true";
            
        } catch (Exception e) {
            
            log.error("ajaxCreateWorkBatch error.", e);
        }
        log.info("批次创建结束{}",System.currentTimeMillis()-tempT);
        return flag;
    }
    
    /**
     * 导向作业批次页面
     * 废弃此方法，新增分页的方法  libin　20160805
     * @param model
     * @param request
     * @return
     */
    @Deprecated
    @RequestMapping(value = "v2_toWorkBatchPageBak")
    public String toWorkBatchPageBak(Model model, ServletRequest request) {
        try {
            
            // 当前用户关联的商家列表
            ShiroUser curUser = (ShiroUser)SecurityUtils.getSubject().getPrincipal();
            List<Customers> customerList = this.customersService.loadCustomerByAuthority(curUser);
            model.addAttribute("customerList", customerList);
            model.addAttribute("userType", curUser.userType);
            
            // 如果是paiu用户,初始化数据
            if ("paiu".equals(curUser.userType)) {
                Map<String, Object> param = new HashMap<String, Object>();
                param.put("customerCodes", StringUtils.isBlank(curUser.customers) ? "blank" : curUser.customers);
                param.put("areagroups", StringUtils.isBlank(curUser.areagroups) ? "blank" : curUser.areagroups);
                param.put("status", "1");
                param.put("batchType", curUser.userType);
                List<WorkBatch> workBatchList = this.workBatchService.loadWorkBatch(param);
                model.addAttribute("workBatchList", workBatchList);
                model.addAttribute("status", "1");
            }
            
            // 如果是商家用户,初始化数据
            if ("customer".equals(curUser.userType)) {
                
                // 初始化仓库数据
                String customerCode = curUser.customerCode;
                model.addAttribute("customerCode", customerCode);
                List<AreaGroup> warehouseList = this.areaGroupService.loadAreaGroupByAuthority(curUser, customerCode);
                model.addAttribute("warehouseList", warehouseList);
                
                Map<String, Object> param = new HashMap<String, Object>();
                param.put("customerCodes", customerCode);
                param.put("areagroups", curUser.areagroups);
                param.put("status", "1");
                param.put("batchType", curUser.userType);
                List<WorkBatch> workBatchList = this.workBatchService.loadWorkBatch(param);
                model.addAttribute("workBatchList", workBatchList);
                model.addAttribute("status", "1");
            }
            
            /* begin add bug:274  创建作业批次跳转回来后保留查询条件 20160613 lianghe.yuan */
            Session session = SecurityUtils.getSubject().getSession();
            Map<String, Object> searchParamMap = new HashMap<String, Object>();
            searchParamMap.put("status", "1");
            session.setAttribute("workBatchListSearchParams", searchParamMap);
            /* end add bug:274  创建作业批次跳转回来后保留查询条件 20160613 lianghe.yuan */
            
        } catch (Exception e) {
            
            log.error("error", e);
        }
        return "work/createTask/workBatchList";
    }
    
    /**
     * 分页方法导向作业批次页面
     * 
     * @param 
     * @return 
     * @throws 
     * @author <a href=mailto:libin@nryuncang.com>libin</a>
     * @version 1.0.0
     */
    @SuppressWarnings("unchecked")
    @RequestMapping(value = "v2_toWorkBatchPage")
    public String toWorkBatchPage(Model model, ServletRequest request) {
        try {
            
            fillSelectValue(model,null);
            ShiroUser curUser = getShiroUser();
            model.addAttribute("userType", curUser.userType);
            model.addAttribute("status", "1");
            
            Session session = SecurityUtils.getSubject().getSession();
            Map<String, String> searchParamMap = (Map<String, String>)session.getAttribute("workBatchListSearchParams");
            if(null!=searchParamMap){
                model.addAttribute("customerCode", searchParamMap.get("customerCode"));
                model.addAttribute("warehouseCode", searchParamMap.get("warehouseCode"));
                model.addAttribute("fromDate", searchParamMap.get("fromDate"));
                model.addAttribute("toDate", searchParamMap.get("toDate"));
                model.addAttribute("pickType", searchParamMap.get("pickType"));
                model.addAttribute("status", searchParamMap.get("status"));
                model.addAttribute("psFlag", searchParamMap.get("psFlag"));
            }
            
        } catch (Exception e) {
            log.error("error", e);
        }
        return "work/createTask/workBatchList";
    }
    
    /**
     * 作业批次的分页的查询方法
     * 
     * @param 
     * @return 
     * @throws 
     * @author <a href=mailto:libin@nryuncang.com>libin</a>
     * @version 1.0.0
     */
    @SuppressWarnings("unchecked")
    @RequestMapping(value = "v2_queryWorkBatch", method = RequestMethod.POST)
    public void queryWorkBatch(@RequestBody JSONParam[] paramJson, HttpServletResponse response){
        
        PrintWriter out = null;
        JSONObject json = null;
        Page<WorkBatch> page = null;
        try {
            out = response.getWriter();
            json = new JSONObject();
            ShiroUser curUser = getShiroUser();
            
            Map<String, String> paramMap = DataTablesUtils.convertToMap(paramJson);
            Session session = SecurityUtils.getSubject().getSession();
            
            if("Y".equals(paramMap.get("flg"))) {
                session.setAttribute("workBatchListSearchParams", paramMap);
            }else {
                Map<String, String> tempParamMap = (Map<String, String>) session.getAttribute("workBatchListSearchParams");
                paramMap = tempParamMap == null ? paramMap : tempParamMap;
            }
            
            int start = Integer.parseInt(paramMap.get("iDisplayStart"));
            int length = Integer.parseInt(paramMap.get("iDisplayLength"));
            int curPage = (start / length) + 1;
            String sEcho = paramMap.get("sEcho");
            Map<String, Object> param = getParameter(curUser, paramMap);
            
            page = workBatchService.loadPageWorkBatch(param, curPage, length);
            List<WorkBatch> workBatchList = page.getContent();
            
            json.put("aaData", workBatchList);
            json.put("sEcho", sEcho);
            json.put("iTotalRecords", page.getTotalElements());
            json.put("iTotalDisplayRecords", page.getTotalElements());
            
            out.print(json);
            
        } catch (Exception e) {
            log.error("搜索查询异常", e);
        }
    }
    
    /**
     * 查询作业批次
     * 废弃该方法，使用分页方法 libin 20160807
     * @param model
     * @param request
     * @param response
     * @return
     * @throws Exception
     */
    @Deprecated
    @RequestMapping(value = "v2_queryWorkBatchBak")
    public String queryWorkBatchBak(Model model, ServletRequest request, ServletResponse response)
        throws Exception
    {
        
        // 查出当前用户关联的商家列表
        ShiroUser curUser = (ShiroUser)SecurityUtils.getSubject().getPrincipal();
        List<Customers> customerList = this.customersService.loadCustomerByAuthority(curUser);
        model.addAttribute("customerList", customerList);
        model.addAttribute("userType", curUser.userType);
        
        // 查询作业批次
        Map<String, Object> searchParams = Servlets.getParametersStartingWith(request, "_");
        
        /* begin add bug:274  创建作业批次跳转回来后保留查询条件 20160612 lianghe.yuan */
        
        Session session = SecurityUtils.getSubject().getSession();
        
        if (searchParams != null && !searchParams.isEmpty()) {
            Map<String, Object> searchParamMap = new HashMap<String, Object>();
            searchParamMap.putAll(searchParams);
            
            session.setAttribute("workBatchListSearchParams", searchParamMap);
        } else {
            searchParams = (Map<String, Object>) session.getAttribute("workBatchListSearchParams");
            searchParams = searchParams == null ? new TreeMap<String, Object>() : searchParams;
        }
        model.addAttribute("fromDate", searchParams.get("fromDate"));
        model.addAttribute("toDate", searchParams.get("toDate"));
        
        /* end add bug:274  创建作业批次跳转回来后保留查询条件 20160612 lianghe.yuan */
        
        String fromDateStr = (String)searchParams.get("fromDate");
        String toDateStr = (String)searchParams.get("toDate");
        String pickType = (String)searchParams.get("pickType");
        String status = (String)searchParams.get("status");
        String warehouseCode = (String)searchParams.get("warehouseCode");
        String customerCode = (String)searchParams.get("customerCode");
        Date fromDate = null;
        Date toDate = null;
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        if (StringUtils.isNotEmpty(fromDateStr)) {
            fromDate = sdf.parse(fromDateStr + " 00:00:00");
        }
        if (StringUtils.isNotEmpty(toDateStr)) {
            toDate = sdf.parse(toDateStr + " 23:59:59");
        }
        
        Map<String, Object> param = new HashMap<String, Object>();
        
        if (StringUtils.isBlank(customerCode)) {
            String customerCodes = this.customersService.loadCustomerByAuthority(curUser.jobuuid);
            param.put("customerCodes", StringUtils.isBlank(customerCodes) ? "blank" : customerCodes);
        } else {
            param.put("customerCodes", customerCode);
        }
        
        if (StringUtils.isBlank(warehouseCode)) {
            param.put("areagroups", StringUtils.isBlank(curUser.areagroups) ? "blank" : curUser.areagroups);
        } else {
            param.put("areagroups", warehouseCode);
        }
        
        param.put("fromDate", fromDate);
        param.put("toDate", toDate);
        param.put("status", status);
        param.put("batchType", curUser.userType);
        param.put("pickType", pickType);
        List<WorkBatch> workBatchList = this.workBatchService.loadWorkBatch(param);
        
        model.addAttribute("workBatchList", workBatchList);
        model.addAttribute("customerCode", customerCode);
        model.addAttribute("warehouseCode", warehouseCode);
        model.addAttribute("pickType", pickType);
        model.addAttribute("status", status);
        
        // 初始化仓库数据
        if (StringUtils.isNotBlank(customerCode)) {
            List<AreaGroup> warehouseList = this.areaGroupService.loadAreaGroupByAuthority(curUser, customerCode);
            model.addAttribute("warehouseList", warehouseList);
        }
        
        return "work/createTask/workBatchList";
    }
    
    @RequestMapping(value = "v2_queryWorkBatchSendout")
    public String toSendoutPage(Model model, ServletRequest request) {
        try {
            
            // 当前用户关联的商家列表
            ShiroUser curUser = (ShiroUser)SecurityUtils.getSubject().getPrincipal();
            // List<Customers> customerList=this.customersService.loadCustomerByAuthority(curUser);
            // model.addAttribute("customerList",customerList);
            List<LogisticsCompany> cmpList = logisticsCompanyService.findAll();
            model.addAttribute("cmpList", cmpList);
            model.addAttribute("userType", curUser.userType);
            fillSelectValue(model, null);
        } catch (Exception e) {
            log.error("error", e);
        }
        return "work/createTask/workBatchSendoutList";
    }
    
    /**
     * 查询已发货的作业批次
     * 废弃该方法，新增分页功能的方法 libin 20160805
     * @param model
     * @param request
     * @param response
     * @return
     * @throws Exception
     */
    @Deprecated
    @RequestMapping(value = "v2_toSendoutPageBak")
    public String queryWorkBatchSendoutBak(Model model, ServletRequest request, ServletResponse response)
        throws Exception
    {
        
        // 查出当前用户关联的商家列表
        ShiroUser curUser = (ShiroUser)SecurityUtils.getSubject().getPrincipal();
        List<Customers> customerList = this.customersService.loadCustomerByAuthority(curUser);
        model.addAttribute("customerList", customerList);
        model.addAttribute("userType", curUser.userType);
        List<LogisticsCompany> cmpList = logisticsCompanyService.findAll();
        model.addAttribute("cmpList", cmpList);
        
        // 查询作业批次
        Map<String, Object> param = new HashMap<String, Object>();
        Map<String, Object> searchParams = Servlets.getParametersStartingWith(request, "_");
        String dataRange = (String)searchParams.get("dataRange");
        // String toDateStr=(String) searchParams.get("toDate");
        String warehouseCode = (String)searchParams.get("warehouseCode");
        String customerCode = (String)searchParams.get("customerCode");
        String batchCode = (String)searchParams.get("batchCode");
        String expressCompany = (String)searchParams.get("expressCompany");
        /*
         * Date fromDate=null;
         * Date toDate=null;
         * SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
         * if(StringUtils.isNotEmpty(fromDateStr)){
         * fromDate=sdf.parse(fromDateStr+" 00:00:00");
         * }
         * if(StringUtils.isNotEmpty(toDateStr)){
         * toDate=sdf.parse(toDateStr+" 23:59:59");
         * }
         */
        if (StringUtils.isNotEmpty(dataRange)) {
            Map<String, Date> dataMap = DateUtils.getDateRange(dataRange);
            Date fromDate = dataMap.get("fromDate");
            Date toDate = dataMap.get("toDate");
            param.put("fromDate", fromDate);
            param.put("toDate", toDate);
        }
        
        if (StringUtils.isBlank(customerCode)) {
            String customerCodes = this.customersService.loadCustomerByAuthority(curUser.jobuuid);
            param.put("customerCodes", StringUtils.isBlank(customerCodes) ? "blank" : customerCodes);
        } else {
            param.put("customerCodes", customerCode);
        }
        
        if (StringUtils.isBlank(warehouseCode)) {
            param.put("areagroups", StringUtils.isBlank(curUser.areagroups) ? "blank" : curUser.areagroups);
        } else {
            param.put("areagroups", warehouseCode);
        }
        if (!StringUtils.isBlank(batchCode)) {
            param.put("batchCode", batchCode);
        }
        if (!StringUtils.isBlank(expressCompany)) {
            param.put("companyCode", expressCompany);
        }
        // param.put("fromDate", fromDate);
        // param.put("toDate", toDate);
        param.put("status", "5");// 只查已发货批次
        param.put("batchType", curUser.userType);
        List<WorkBatch> workBatchList = this.workBatchService.loadWorkBatch(param);
        
        model.addAttribute("workBatchList", workBatchList);
        model.addAttribute("customerCode", customerCode);
        model.addAttribute("warehouseCode", warehouseCode);
        
        // 初始化仓库数据
        /*
         * if(StringUtils.isNotBlank(customerCode)){
         * List<AreaGroup> warehouseList=this.areaGroupService.loadAreaGroupByAuthority(curUser,customerCode);
         * model.addAttribute("warehouseList", warehouseList);
         * }
         */
        fillSelectValue(model, customerCode);
        
        return "work/createTask/workBatchSendoutList";
    }
    
    /**
     * 发货清单的分页的查询方法
     * 
     * @param 
     * @return 
     * @throws 
     * @author <a href=mailto:libin@nryuncang.com>libin</a>
     * @version 1.0.0
     */
    @RequestMapping(value = "v2_toSendoutPage", method = RequestMethod.POST)
    public void queryWorkBatchSendout(@RequestBody JSONParam[] paramJson, HttpServletResponse response){
        
        PrintWriter out = null;
        JSONObject json = null;
        Page<WorkBatch> page = null;
        try {
            out = response.getWriter();
            json = new JSONObject();
            ShiroUser curUser = getShiroUser();
            Map<String, String> paramMap = DataTablesUtils.convertToMap(paramJson);
            
            int start = Integer.parseInt(paramMap.get("iDisplayStart"));
            int length = Integer.parseInt(paramMap.get("iDisplayLength"));
            int curPage = (start / length) + 1;
            String sEcho = paramMap.get("sEcho");
            paramMap.put("status", "5");
            Map<String, Object> param = getParameter(curUser, paramMap);
            
            page = workBatchService.loadPageWorkBatch(param, curPage, length);
            List<WorkBatch> workBatchList = page.getContent();
            
            json.put("aaData", workBatchList);
            json.put("sEcho", sEcho);
            json.put("iTotalRecords", page.getTotalElements());
            json.put("iTotalDisplayRecords", page.getTotalElements());
            
            out.print(json);
            
        } catch (Exception e) {
            log.error("搜索查询异常", e);
        }
    }
    
    /**
     * 组合查询参数
     * 
     * @param 
     * @return 
     * @throws 
     * @author <a href=mailto:libin@nryuncang.com>libin</a>
     * @version 1.0.0
     */
    private Map<String, Object> getParameter(ShiroUser curUser, Map<String, String> paramMap) throws Exception{
        
        Map<String, Object> param = new HashMap<String, Object>();

        if (StringUtils.isNotEmpty(paramMap.get("dataRange"))) {
            Map<String, Date> dataMap = DateUtils.getDateRange(paramMap.get("dataRange"));
            Date fromDate = dataMap.get("fromDate");
            Date toDate = dataMap.get("toDate");
            param.put("fromDate", fromDate);
            param.put("toDate", toDate);
        }else {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            if (StringUtils.isNotEmpty(paramMap.get("fromDate"))) {
                param.put("fromDate", sdf.parse(paramMap.get("fromDate") + " 00:00:00"));
            }
            if (StringUtils.isNotEmpty(paramMap.get("toDate"))) {
                param.put("toDate", sdf.parse(paramMap.get("toDate") + "  23:59:59"));
            }
        }
        if (StringUtils.isBlank(paramMap.get("customerCode"))) {
            String customerCodes = this.customersService.loadCustomerByAuthority(curUser.jobuuid);
            param.put("customerCodes", StringUtils.isBlank(customerCodes) ? "blank" : customerCodes);
        } else {
            param.put("customerCodes", paramMap.get("customerCode"));
        }
        if (StringUtils.isBlank(paramMap.get("warehouseCode"))) {
            param.put("areagroups", StringUtils.isBlank(curUser.areagroups) ? "blank" : curUser.areagroups);
        } else {
            param.put("areagroups", paramMap.get("warehouseCode"));
        }
        if (!StringUtils.isBlank(paramMap.get("batchCode"))) {
            param.put("batchCode", paramMap.get("batchCode"));
        }
        if (!StringUtils.isBlank(paramMap.get("expressCompany"))) {
            param.put("companyCode", paramMap.get("expressCompany"));
        }
        if (!StringUtils.isBlank(paramMap.get("pickType"))) {
            param.put("pickType", paramMap.get("pickType"));
        }
        
        param.put("status", paramMap.get("status"));// 只查已发货批次
        param.put("batchType", curUser.userType);
        
        param.put("psFlag", paramMap.get("psFlag"));// 优先派送标志
        
        return param;
    }
    
    /**
     * 导出发货清单
     * 
     * @param model
     * @param request
     * @param response
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "exportExcel")
    public void exportExcel(ServletRequest request, HttpServletResponse response)
        throws Exception
    {
        // 查出当前用户关联的商家列表
        ShiroUser curUser = (ShiroUser)SecurityUtils.getSubject().getPrincipal();
        String moban = request.getParameter("moban");// 模板 ：GY-管易 YHD-一号店 PY-派友
        List<Customers> customers = customersService.loadCustomerByAuthority(curUser);
        // 查询作业批次
        Map<String, Object> param = new HashMap<String, Object>();
        Map<String, Object> searchParams = Servlets.getParametersStartingWith(request, "_");
        String dataRange = (String)searchParams.get("dataRange");
        String warehouseCode = (String)searchParams.get("warehouseCode");
        String customerCode = (String)searchParams.get("customerCode");
        checkArgument(StringUtils.isNotEmpty(dataRange), "dataRange is empty");
        log.info("{} 导出发货清单 {}", curUser.realname, dataRange);
        
        param.put("status", "5");// 只查已发货批次
        param.put("batchType", curUser.userType);
        long start = System.currentTimeMillis();
        try {
            response.setContentType("application/ostet-stream");
            String outFileName = new StringBuilder().append(customerCode)
                .append("-")
                .append(warehouseCode)
                .append("(")
                .append(dataRange.replaceAll("\\s", ""))
                .append(")")
                .toString();
            response.setHeader("Content-disposition", "attachment; filename=" + outFileName + ".zip");
            
            /*
             * 针对东莞仓，单独使用模板。 业务流程： 1、判断是否为东莞仓的导出，是则采用新模板，解析完成直接返回
             * 2、获取表头
             * 3、获取数据总量
             * 4、数据量较多的情况下，是否需要提示用户修改查询时间
             * 3、判断是否需要分页从数据库获取数据
             * 4、数据封装
             * 5、数据写入xls
             * 6、响应
             * 
             * @author zhangpeijun
             */
            if (Constants.WH_CODE_DONGGUAN.equals(warehouseCode)) {
                if (LOG.isDebugEnabled()) {
                    
                }
                // 只查询已发货的数据。
                Map<String, Object> expParam = new HashMap<String, Object>();
                expParam.put("orderStatus", "ok");
                expParam.put("status", "finish");
                expParam.put("workOrderStatus", "6");
                expParam.put("customerCode", customerCode);
                expParam.put("warehouseCode", Constants.WH_CODE_DONGGUAN);
                if (StringUtils.isNotEmpty(dataRange)) {
                    Map<String, Date> dataMap = DateUtils.getDateRange(dataRange);
                    Date fromDate = dataMap.get("fromDate");
                    Date toDate = dataMap.get("toDate");
                    expParam.put("fromDate", fromDate);
                    expParam.put("toDate", toDate);
                }
                // 获取表头
                CustomerLead customerLead = customerLeadService.findByCustomerCodeAndOrdenoSource(Constants.WH_CODE_TABLE_HEAD,
                    "");
                List<TablePojo> xlsMode = DataTablesUtils.getTablePojo(customerLead);
                // 获取数据总量
                // TODO 当数据量超过某个值时，可提示用户调整查询时间，减小数据量查询。
                // long orderCount = ediOrderDtoService.loadOrderCount(expParam);
                // List<EdiOrderDto> orderList = ediOrderDtoService.findAll(expParam);
                // 封装第一个模板的数据
                List<VEdiOrder> vOrderList = vEdiOrderService.findAll(expParam);
                xlsMode.get(0).setBodys(orderObj2ExpMode(vOrderList));
                // 封装第二个模板的数据
                List<VEdiOrderItem> vItemList = vEdiOrderItemService.findAll(expParam);
                xlsMode.get(1).setBodys(orderItemObj2ExpMode(vItemList));
                String fullName = ExcelUtils.TEMPPATH + File.separator + Constants.WH_CODE_DONGGUAN + "-"
                    + TimeUtil.getNowDateStringDD() + "-" + System.currentTimeMillis() + ".xls";
                ExcelUtils.createAndWrite2Excel(fullName, xlsMode);
                // 维持原有的下载模式，写入响应流中下载文件。
                writeDoladFile(new File(fullName), response);
                return;
            }
            
            if ("PY".equals(moban)) {
                if (StringUtils.isNotEmpty(dataRange)) {
                    Map<String, Date> dataMap = DateUtils.getDateRange(dataRange);
                    Date fromDate = dataMap.get("fromDate");
                    Date toDate = dataMap.get("toDate");
                    searchParams.put("fromDate", fromDate);
                    searchParams.put("toDate", toDate);
                }
                if (StringUtils.isBlank(customerCode)) {
                    String customerCodes = this.customersService.loadCustomerByAuthority(curUser.jobuuid);
                    searchParams.put("customerCodes", StringUtils.isBlank(customerCodes) ? "blank" : customerCodes);
                } else {
                    searchParams.put("customerCodes", customerCode);
                }
                
                if (StringUtils.isBlank(warehouseCode)) {
                    searchParams.put("areagroups", StringUtils.isBlank(curUser.areagroups) ? "blank"
                        : curUser.areagroups);
                } else {
                    searchParams.put("areagroups", warehouseCode);
                }
                
                searchParams.put("status", "6");
                searchParams.put("cancelStatus", "ok");
                
                String fileName = new StringBuilder().append(InitProperties.get("excel.download.path"))
                    .append(File.separator)
                    .append("file")
                    .append(File.separator)
                    .append(DateUtils.getYYYYMMDDDate())
                    .append(File.separator)
                    .append(UUID.randomUUID())
                    .append(".xls")
                    .toString();
                File excelFile = new File(fileName);
                if (!excelFile.getParentFile().exists()) {
                    excelFile.getParentFile().mkdirs();
                }
                excelFile.createNewFile();
                long orderCount = workOrderService.loadOrderCount(searchParams);
                int pageNumber = 1;// 页数
                int pageSize = 5000;// 每次查询数据库的数量
                int sheetTotalSize = 50000;// 每页sheet内的行数
                int sheetIndex = 0;// excel中sheet的数量
                ForkJoinPool pool = new ForkJoinPool();
                WritableWorkbook book = Workbook.createWorkbook(excelFile);
                WritableSheet sheet = null;
                for (int i = 0; i < orderCount; i += pageSize) {
                    if (sheet == null || i >= sheetTotalSize * sheetIndex) {
                        sheet = createSheet(book, sheetIndex++);
                    }
                    SheetSendOut sheetSendOut = new SheetSendOut();
                    sheetSendOut.searchParams = searchParams;
                    sheetSendOut.pageNumber = pageNumber;
                    sheetSendOut.pageSize = pageSize;
                    sheetSendOut.customers = customers;
                    sheetSendOut.sheet = sheet;
                    sheetSendOut.begin2Write = ((pageNumber - 1) * pageSize + 1) % sheetTotalSize;
                    
                    pageNumber++;
                    SubWriteExcelTask subTask = new SubWriteExcelTask(sheetSendOut);
                    pool.execute(subTask);
                }
                pool.shutdown();
                pool.awaitTermination(30, TimeUnit.MINUTES);
                log.info("导出order size:{}", orderCount);
                if (orderCount > 0) {
                    book.write();
                    book.close();
                }
                ExcelUtils.writeOutZip(response.getOutputStream(), excelFile);
            } else if ("QCT".equals(moban)) {
                DateFormat df = new SimpleDateFormat("yyyy/MM/dd");
                String[] titles = {"运单编号", "寄件日期", "短信通知", "取件员", "省份", "目的地", "支付方式", "快件类型", "实际重量", "件数", "收件人",
                    "收件电话", "收件手机", "收件地址"};
                List<Object[]> rs = new ArrayList<Object[]>();
                
                if (StringUtils.isNotEmpty(dataRange)) {
                    Map<String, Date> dataMap = DateUtils.getDateRange(dataRange);
                    Date fromDate = dataMap.get("fromDate");
                    Date toDate = dataMap.get("toDate");
                    searchParams.put("fromDate", fromDate);
                    searchParams.put("toDate", toDate);
                }
                if (StringUtils.isBlank(customerCode)) {
                    String customerCodes = this.customersService.loadCustomerByAuthority(curUser.jobuuid);
                    searchParams.put("customerCodes", StringUtils.isBlank(customerCodes) ? "blank" : customerCodes);
                } else {
                    searchParams.put("customerCodes", customerCode);
                }
                
                if (StringUtils.isBlank(warehouseCode)) {
                    searchParams.put("areagroups", StringUtils.isBlank(curUser.areagroups) ? "blank"
                        : curUser.areagroups);
                } else {
                    searchParams.put("areagroups", warehouseCode);
                }
                searchParams.put("cancelStatus", "ok");
                searchParams.put("expressCompany", "QRT");
                searchParams.put("status", "6");
                
                int pageNumber = 1;
                int pageSize = 1000;
                int workOrdersSize = 0;
                while (true) {
                    List<WorkOrderNoCascade> workOrders = this.workOrderService.loadOrderPage(searchParams,
                        pageNumber,
                        pageSize);
                    pageNumber++;
                    workOrdersSize += workOrders.size();
                    if (workOrders.size() == 0) {
                        break;
                    }
                    for (WorkOrderNoCascade wo : workOrders) {
                        if ("ok".equals(wo.getCancelStatus()) && "QRT".equals(wo.getExpressCompany())) {
                            EdiOrder order = wo.getOrder();
                            String temp = order.getRecena();
                            String recena = temp;
                            if (temp.length() > 3) {
                                recena = temp.substring(0, 3);
                            }
                            Object[] object = {
                                StatusEnums.WAYBILL_TYPE_CBILL.getStatus().equals(wo.getBillType()) ? wo.getExpressNo()
                                    : wo.getEbillNo(), df.format(wo.getCreateTime()), "1", "取件员1", order.getProvna(),
                                order.getCityna(), "寄付现金", "汽运",
                                wo.getWeight() == null ? null : wo.getWeight() / 1000.0, 1, recena,
                                StringUtils.isBlank(order.getMobile()) ? order.getTeleph() : order.getMobile(),
                                StringUtils.isBlank(order.getMobile()) ? order.getTeleph() : order.getMobile(),
                                order.getAddres(), null};
                            rs.add(object);
                        }
                    }
                }
                log.info("导出workBatchsize:" + workOrdersSize);
                ExcelUtils.writeExcel(titles, "Sheet1", rs, response.getOutputStream());
            }
            
            long end = System.currentTimeMillis();
            log.info("导出耗时[{}] ms", (end - start));
        } catch (Exception e) {
            log.error("export excel error.", e);
        }
    }
    
    private class SubWriteExcelTask extends RecursiveAction {
        private static final long serialVersionUID = 1L;
        
        private SheetSendOut sheetSendOut;
        
        SubWriteExcelTask(SheetSendOut sheetSendOut) {
            this.sheetSendOut = sheetSendOut;
        }
        
        @Override
        protected void compute() {
            try {
                List<WorkOrderNoCascade> workOrders = workOrderService.loadOrderPage(sheetSendOut.searchParams,
                    sheetSendOut.pageNumber,
                    sheetSendOut.pageSize);
                write2Sheet(sheetSendOut, workOrders);
            } catch (Exception e) {
                log.error("error", e);
            }
        }
    }
    
    private void write2Sheet(SheetSendOut sheetSendOut, List<WorkOrderNoCascade> workOrders)
        throws WriteException, RowsExceededException
    {
        DateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        WritableSheet sheet = sheetSendOut.sheet;
        int rowIndex = sheetSendOut.begin2Write;
        List<Customers> customers = sheetSendOut.customers;
        for (WorkOrderNoCascade wo : workOrders) {
            if ("ok".equals(wo.getCancelStatus())) {
                String customerName = "";
                for (Customers cs : customers) {
                    if (wo.getCustomerCode().equals(cs.getCustomerCode())) {
                        customerName = cs.getCustomerName();
                        break;
                    }
                }
                int columnIndex = 0;
                sheet.addCell(new Label(columnIndex++, rowIndex, customerName));
                sheet.addCell(new Label(columnIndex++, rowIndex, wo.getOrder().getCustomerOrdeno()));
                sheet.addCell(new Label(columnIndex++, rowIndex, wo.getOrder().getFromno()));
                sheet.addCell(new Label(columnIndex++, rowIndex, wo.getOrder().getOrdeno()));
                StringBuffer goodsName = new StringBuffer("");
                List<EdiOrderItem> orderItem = wo.getOrder().getOrderItems();
                if (orderItem.size() > 0) {
                    for (int i = 0; i < orderItem.size(); i++) {
                        goodsName.append(orderItem.get(i).getNam());
                        goodsName.append(":").append(orderItem.get(i).getQty());
                        goodsName.append("; ");
                    }
                    goodsName.replace(goodsName.length() - 2, goodsName.length(), " ");
                }
                sheet.addCell(new Label(columnIndex++, rowIndex, goodsName.toString()));
                sheet.addCell(new Label(columnIndex++, rowIndex, format.format(wo.getFinishTime())));
                sheet.addCell(new Label(columnIndex++, rowIndex, wo.getExpressCompany()));
                sheet.addCell(new Label(columnIndex++, rowIndex, StatusEnums.WAYBILL_TYPE_CBILL.getStatus()
                    .equals(wo.getBillType()) ? wo.getExpressNo() : wo.getEbillNo()));
                sheet.addCell(new Label(columnIndex++, rowIndex, String.valueOf(wo.getWeight() == null ? 0
                    : wo.getWeight() * 1.0 / 1000))); // 重量
                sheet.addCell(new Label(columnIndex++, rowIndex, String.valueOf(wo.getSysWeight() == null ? 0
                    : wo.getSysWeight() * 1.0 / 1000))); // 重量
                sheet.addCell(new Label(columnIndex++, rowIndex, wo.getOrder().getRecena()));
                sheet.addCell(new Label(columnIndex++, rowIndex,
                    StringUtils.isBlank(wo.getOrder().getMobile()) ? wo.getOrder().getTeleph() : wo.getOrder()
                        .getMobile()));
                sheet.addCell(new Label(columnIndex++, rowIndex, wo.getOrder().getAddres()));
                sheet.addCell(new Label(columnIndex++, rowIndex, String.valueOf(wo.getOrder().getSkuQty())));
                sheet.addCell(new Label(columnIndex++, rowIndex, wo.getGoodsInfo()));
                sheet.addCell(new Label(columnIndex++, rowIndex, wo.getOrder().getProvna()));
                sheet.addCell(new Label(columnIndex++, rowIndex, wo.getOrder().getCityna()));
                sheet.addCell(new Label(columnIndex++, rowIndex, wo.getOrder().getDistna()));
                sheet.addCell(new Label(columnIndex++, rowIndex, wo.getGoodsNum() > 1 ? "多件" : "单件"));
                
                //bug594  添加批次号 by zhangweize 2016-10-31
                sheet.addCell(new Label(columnIndex++, rowIndex, wo.getBatchCode()));
                //添加店铺名称 bug611 add LiBin 20161116
                sheet.addCell(new Label(columnIndex++, rowIndex, wo.getShopna()));
                rowIndex++;
            }
        }
    }
    
    private class SheetSendOut {
        private int begin2Write;// sheet中开始写入的行
        
        private List<Customers> customers;//
        
        private WritableSheet sheet;//
        
        private Map<String, Object> searchParams;
        
        private int pageNumber;
        
        private int pageSize;
    }
    
    private WritableSheet createSheet(WritableWorkbook book, int sheetIndex)
        throws WriteException, RowsExceededException
    {
        WritableSheet sheet = book.createSheet(new StringBuilder().append("发货清单(")
            .append(sheetIndex++)
            .append(")")
            .toString(), sheetIndex);
        /*
         * WritableFont BoldFont = new WritableFont(WritableFont.ARIAL, 10,WritableFont.BOLD);
         * WritableCellFormat wcf_center = new WritableCellFormat(BoldFont);
         * wcf_center.setWrap(false); // 文字是否换行
         */
        int columnIndex = 0;
        sheet.setColumnView(columnIndex++, 15);
        sheet.setColumnView(columnIndex++, 30);
        sheet.setColumnView(columnIndex++, 30);
        sheet.setColumnView(columnIndex++, 30);
        sheet.setColumnView(columnIndex++, 15);
        sheet.setColumnView(columnIndex++, 12);
        sheet.setColumnView(columnIndex++, 18);
        sheet.setColumnView(columnIndex++, 12);
        sheet.setColumnView(columnIndex++, 12);
        sheet.setColumnView(columnIndex++, 12);
        sheet.setColumnView(columnIndex++, 18);
        sheet.setColumnView(columnIndex++, 20);
        sheet.setColumnView(columnIndex++, 80);
        sheet.setColumnView(columnIndex++, 12);
        sheet.setColumnView(columnIndex++, 12);
        sheet.setColumnView(columnIndex++, 12);
        sheet.setColumnView(columnIndex++, 12);
        sheet.setColumnView(columnIndex++, 12);
        sheet.setColumnView(columnIndex++, 12);
        
        //bug594  添加批次号 by zhangweize 2016-10-31
        sheet.setColumnView(columnIndex++, 30);
        sheet.setColumnView(columnIndex++, 30);
        int cIndex = 0;
        sheet.addCell(new Label(cIndex++, 0, "商家"));
        sheet.addCell(new Label(cIndex++, 0, "客户订单号"));
        sheet.addCell(new Label(cIndex++, 0, "来源单号"));
        sheet.addCell(new Label(cIndex++, 0, "派友单号"));
        sheet.addCell(new Label(cIndex++, 0, "商品名称"));
        sheet.addCell(new Label(cIndex++, 0, "发货时间"));
        sheet.addCell(new Label(cIndex++, 0, "快递公司"));
        sheet.addCell(new Label(cIndex++, 0, "快递单号"));
        sheet.addCell(new Label(cIndex++, 0, "发货重量"));
        sheet.addCell(new Label(cIndex++, 0, "系统配置重量"));
        sheet.addCell(new Label(cIndex++, 0, "收件人"));
        sheet.addCell(new Label(cIndex++, 0, "电话"));
        sheet.addCell(new Label(cIndex++, 0, "地址"));
        sheet.addCell(new Label(cIndex++, 0, "商品数量"));
        sheet.addCell(new Label(cIndex++, 0, "商品信息"));
        sheet.addCell(new Label(cIndex++, 0, "省"));
        sheet.addCell(new Label(cIndex++, 0, "市"));
        sheet.addCell(new Label(cIndex++, 0, "区"));
        sheet.addCell(new Label(cIndex++, 0, "订单类型"));
        
      //bug594  添加批次号 by zhangweize 2016-10-31
        sheet.addCell(new Label(cIndex++, 0, "批次号"));
        sheet.addCell(new Label(cIndex++, 0, "店铺名称"));
        return sheet;
    }
    
    /**
     * 导出发货清单
     * 
     * @param model
     * @param request
     * @param response
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "exportExcelGY/{batchCode}")
    public void exportExcelGY(@PathVariable("batchCode") String batchCode, HttpServletResponse response)
        throws Exception
    {
        try {
            response.setContentType("application/vnd.ms-excel");
            response.setHeader("Content-disposition", "attachment; filename=" + batchCode + ".xls");
            
            WritableWorkbook book = Workbook.createWorkbook(response.getOutputStream());
            WritableSheet sheet = book.createSheet("Sheet1 ", 0);
            sheet.setColumnView(0, 30);// 订单编号
            sheet.setColumnView(1, 15);// 来源单号
            sheet.setColumnView(2, 20);// 物流公司名称
            sheet.setColumnView(3, 20);// 物流单号
            sheet.setColumnView(4, 15);// 物流成本
            sheet.setColumnView(5, 15);// 称重重量
            Label label1 = new Label(0, 0, "订单编号");
            sheet.addCell(label1);
            Label label2 = new Label(1, 0, "来源单号");
            sheet.addCell(label2);
            Label label3 = new Label(2, 0, "物流公司名称");
            sheet.addCell(label3);
            Label label4 = new Label(3, 0, "物流单号");
            sheet.addCell(label4);
            Label label5 = new Label(4, 0, "物流成本");
            sheet.addCell(label5);
            Label label6 = new Label(5, 0, "称重重量");
            sheet.addCell(label6);
            int index_1 = 1;
            List<WorkOrder> workOrders = this.workOrderService.loadOrderByBatchCode(batchCode);
            for (WorkOrder wo : workOrders) {
                Label label111 = new Label(0, index_1, wo.getOrder().getCustomerOrdeno());
                sheet.addCell(label111);
                Label label211 = new Label(1, index_1, "");
                sheet.addCell(label211);
                Label label311 = new Label(2, index_1, "");
                sheet.addCell(label311);
                String expressNo = "";
                if ("cbill".equals(wo.getBillType())) {
                    expressNo = wo.getExpressNo();
                } else {
                    expressNo = wo.getEbillNo();
                }
                Label label411 = new Label(3, index_1, expressNo);
                sheet.addCell(label411);
                Label label511 = new Label(4, index_1, "");
                sheet.addCell(label511);
                Label label611 = new Label(5, index_1, "");
                sheet.addCell(label611);
                index_1++;
            }
            book.write();
            book.close();
            
        } catch (Exception e) {
            // TODO Auto-generated catch block
            
        }
        
    }
    
    /**
     * 推送出库批次
     * 
     * @param model
     * @param request
     * @return
     */
    @RequestMapping(value = "toCreateBatch", method = RequestMethod.POST)
    public void toCreateBatch(@RequestParam("batchCode") String batchCode, HttpServletResponse response) {
        JSONObject json = null;
        PrintWriter out = null;
        try {
            json = new JSONObject();
            out = response.getWriter();
            WorkBatch workBatch = this.workBatchService.loadWorkBatchByCode(batchCode);
            if (null == workBatch) {
                json.put("status", "0"); // 包装成功
                json.put("content", "批次号不能为空");
                out.print(json.toString());
                return;
            } else {
                Batch batch = new Batch();
                batch.setBox_num(1);
                batch.setCustomer_code(workBatch.getCustomerCode());
                batch.setBatch(workBatch.getBatchCode());
                batch.setEndpoints(workBatch.getWarehouseCode());
                batch.setShipped_time(TimeUtil.getNowDateString(workBatch.getCreateTime()));
                batch.setStartpoints("0755");
                List<Box> boxList = new ArrayList<Box>();
                List<Order> orderList = new ArrayList<Order>();
                List<WorkTask> workTasks = this.workTaskService.loadTaskByBatchCode(workBatch.getBatchCode());
                
                for (WorkTask wt : workTasks) {
                    Box box = new Box();
                    box.setBox_code(wt.getTaskCode());
                    box.setBox_type(workBatch.getPickType());
                    box.setGoods_num(Integer.parseInt(wt.getGoodsNum() + ""));
                    box.setWeight(0);
                    
                    List<Box_detail> skuList = new ArrayList<Box_detail>();
                    List<WorkTaskItem> wtis = workTaskItemService.loadByTaskCode(wt.getTaskCode());
                    for (WorkTaskItem wti : wtis) {
                        Box_detail sku = new Box_detail();
                        sku.setBox(box.getBox_code());
                        sku.setNum(wti.getPickedNum());
                        sku.setSku(wti.getSku());
                        skuList.add(sku);
                    }
                    box.setBox_detail(skuList);
                    boxList.add(box);
                }
                
                int sun_num = 0;
                List<WorkOrder> workOrders = this.workOrderService.loadOrderByBatchCode(batchCode);
                for (WorkOrder wo : workOrders) {
                    Order order = new Order();
                    order.setOrdeno(wo.getOrder().getOrdeno());
                    order.setFromno(wo.getOrder().getFromno());
                    order.setOrder_type(workBatch.getPickType());
                    order.setSku_num(wo.getGoodsNum());
                    String expressNo = "";
                    if ("cbill".equals(wo.getBillType())) {
                        expressNo = wo.getExpressNo();
                    } else {
                        expressNo = wo.getEbillNo();
                    }
                    order.setExpressNo(expressNo);
                    order.setExpressCode(wo.getExpressCompany());
                    order.setExpressName(wo.getExpressName());
                    
                    Integer wi = wo.getWeight();
                    if (null == wi) {
                        wi = 0;
                    }
                    order.setWeight(wi);
                    sun_num += wo.getGoodsNum();
                    orderList.add(order);
                }
                
                batch.setGoods_num(sun_num);
                batch.setOrder_num(workBatch.getOrderQty());
                batch.setBox(boxList);
                batch.setOrder(orderList);
                ObjectMapper objectMapper = new ObjectMapper();
                try {
                    String result = SystemUtil.pub("http://tms.paiu.com.cn/tms/api/wms/batch",
                        "appkey=123&appsecret=123&data=" + objectMapper.writeValueAsString(batch));
                    JSONObject json2 = JSONObject.fromObject(result);
                    String status = json2.getString("status");
                    if ("1".equals(status)) {
                        workBatch.setSyncStatus("finish");
                        this.workBatchService.updateBatch(workBatch);
                    }
                    log.info("推送结果：" + result);
                    out.print(result);
                } catch (JsonGenerationException e) {
                    // TODO Auto-generated catch block
                    
                } catch (JsonMappingException e) {
                    // TODO Auto-generated catch block
                    
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    
                }
            }
            
        } catch (Exception e) {
            
            log.error("error", e);
        }
    }
    
    /**
     * 发货
     * 
     * @param model
     * @param request
     * @return
     */
    @RequestMapping(value = "sendGoods", method = RequestMethod.POST)
    public void sendGoods(@RequestParam("batchCode") String batchCode, HttpServletResponse response) {
        JSONObject json = null;
        PrintWriter out = null;
        try {
            json = new JSONObject();
            out = response.getWriter();
            WorkBatch workBatch = this.workBatchService.loadWorkBatchByCode(batchCode);
            if (null == workBatch) {
                json.put("status", "0");
                json.put("content", "批次号不能为空");
                out.print(json.toString());
                return;
            }
            List<WorkOrder> workOrders = this.workOrderService.loadOrderByBatchCode(batchCode);
            String address = "http://121.199.162.25/openService/sendOrders.ht";
            log.info("伟易达开始发货：" + batchCode);
            for (WorkOrder wo : workOrders) {
                String[] customersOrdeno = wo.getOrder().getCustomerOrdeno().split(":");
                for (String co : customersOrdeno) {
                    if (!"".equals(co)) {
                        StringBuffer sb = new StringBuffer();
                        sb.append("orderCode=" + co);
                        String expressNo = "";
                        if ("cbill".equals(wo.getBillType())) {
                            expressNo = wo.getExpressNo();
                        } else {
                            expressNo = wo.getEbillNo();
                        }
                        sb.append("&expressCode=" + expressNo);
                        sb.append("&logisticCode=" + wo.getExpressCompany());
                        sb.append("&appkey=123");
                        sb.append("&appsecret=123");
                        log.info("参数名:" + sb.toString());
                        String result = HttpPost.pub(address, sb.toString());
                        log.info("调用订单返回值：" + result);
                    }
                }
            }
        } catch (Exception e) {
            
            log.error("error", e);
        }
        json.put("status", "1");
        json.put("content", "发货成功");
        out.print(json.toString());
        return;
    }
    
    /**
     * 下载文件，写入HttpServletResponse中
     * 
     * @param file
     * @param response [参数说明]
     * 
     * @return void [返回类型说明]
     * @exception throws [违例类型] [违例说明]
     * @see [类、类#方法、类#成员]
     * @author zhangpeijun
     */
    private void writeDoladFile(File file, HttpServletResponse response) {
        try {
            if (null == file) {
                return;
            }
            response.setContentType("application/ostet-stream");
            String name = file.getName();
            if (!name.endsWith(".zip")) {
                name = name.substring(0, name.lastIndexOf(".")) + ".zip";
            }
            response.setHeader("Content-disposition", "attachment; filename=" + name);
            ExcelUtils.writeOutZip(response.getOutputStream(), file);
        } catch (IOException e) {
            log.error("writeDoladFile error.", e);
        } catch (Exception e) {
            log.error("writeDoladFile error.", e);
        }
    }
    
    /**
     * 
     * @return void [返回类型说明]
     * @exception throws [违例类型] [违例说明]
     * @see [类、类#方法、类#成员]
     * @author zhangpeijun
     * @throws ParseException
     */
    private List<String[]> orderObj2ExpMode(List<VEdiOrder> orderList)
        throws ParseException
    {
        List<String[]> orders = null;
        String[] sheetOrder = null;
        // 获取表头的长度
        if (null != orderList && orderList.size() > 0) {
            orders = new ArrayList<String[]>(orderList.size());
            for (VEdiOrder order : orderList) {
                sheetOrder = new String[19];
                sheetOrder[0] = getStringVal(order.getOrderno());
                sheetOrder[1] = getStringVal(null == order.getOrdertime() ? ""
                    : TimeUtil.getNowDateString(order.getOrdertime(), TimeUtil.DF_YYYYMMDDHHMISS));
                sheetOrder[2] = getStringVal(order.getPayment());
                // 币制 --currency - 新增字段
                sheetOrder[3] = getStringVal(order.getCurr());
                sheetOrder[4] = getStringVal(order.getWaybillno());
                sheetOrder[5] = getStringVal(order.getFreight());
                sheetOrder[6] = getStringVal(order.getGrosswt());
                // 净重 --suttle_weight- 新增
                sheetOrder[7] = getStringVal(order.getNetwt());
                sheetOrder[8] = getStringVal(order.getPackno());
                // 身份证 -- rece_id_number -- 新增字段
                sheetOrder[9] = getStringVal(order.getConsigneeId());
                sheetOrder[10] = getStringVal(order.getConsigneeName());
                sheetOrder[11] = getStringVal(order.getConsigneeAddress());
                sheetOrder[12] = getStringVal(order.getConsigneePhone());
                // 收件人所在国 -- rece_country-- 新增字段
                sheetOrder[13] = getStringVal(order.getConsigneeCountry());
                sheetOrder[14] = getStringVal(order.getShipperName());
                sheetOrder[15] = getStringVal(order.getShipperAddress());
                sheetOrder[16] = getStringVal(order.getShipperPhone());
                // 发件人所在国 -- consignor.send_country -
                sheetOrder[17] = getStringVal(order.getShipperCountry());
                sheetOrder[18] = order.getNotes();
                orders.add(sheetOrder);
            }
        }
        return orders;
    }
    
    private List<String[]> orderItemObj2ExpMode(List<VEdiOrderItem> orderList)
        throws ParseException
    {
        List<String[]> orderItems = null;
        String[] sheetOrder = null;
        if (null != orderList && orderList.size() > 0) {
            orderItems = new ArrayList<String[]>(orderList.size());
            for (VEdiOrderItem item : orderList) {
                sheetOrder = new String[12];
                sheetOrder[0] = getStringVal(item.getOrderno());
                sheetOrder[1] = getStringVal(item.getGid());
                sheetOrder[2] = getStringVal(item.getShelfgName());
                // 行邮税号 -- seaway_mail_number -- 新增
                sheetOrder[3] = getStringVal(item.getNcadcode());
                // 海关编码Hscode --haikwan_code -- 新增
                sheetOrder[4] = getStringVal(item.getCodets());
                // 原产国 --origin_country -- 新增
                sheetOrder[5] = getStringVal(item.getOriginCountry());
                sheetOrder[6] = getStringVal(item.getCqty());
                sheetOrder[7] = getStringVal(item.getDeclprice());
                sheetOrder[8] = getStringVal(item.getDecltotal());
                // 单位 -- unit 单位 -- 新增
                sheetOrder[9] = getStringVal(item.getGunit());
                // 币制 -- currency --新增
                sheetOrder[10] = getStringVal(item.getCurr());
                sheetOrder[11] = getStringVal(item.getNotes());
                orderItems.add(sheetOrder);
            }
        }
        return orderItems;
    }
    
    private String getStringVal(Object obj) {
        return null == obj ? "" : String.valueOf(obj);
    }
    
    /**
     * 导出含备注订单
     * 
     *
     * @param model
     * @param request
     * @param response
     * @return [参数说明]
     * @author <a href=mailto:zhangweize@nryuncang.com>zhangweize</a>
     * @version 1.0.0
     */
	@RequestMapping(value = "exceptRemarkOrdernos")
	public String exceptRemarkOrdernos(Model model, ServletRequest request,ServletResponse response){
		FileInputStream f=null;
		OutputStream output=null;
		try {
			Date now=new Date();
			DateFormat df=new SimpleDateFormat("yyyyMMddhhmmss");
			
			//查询数据
			Map<String, Object> searchParams = Servlets.getParametersStartingWith(request, "_");
			String warehouseCode=(String) searchParams.get("warehouseCode");
			String customerCode=(String) searchParams.get("customerCode");
			String fromDate = (String)searchParams.get("fromDate");
			String toDate = (String)searchParams.get("toDate");
			
			List<Object[]> list = new ArrayList<Object[]>();

		    list = ediOrderService.exceptRemarkOrdernos(customerCode, warehouseCode, fromDate, toDate);

			// modify 当数据超过6W行时，ExcelUtils.writeExcel(...) 不支持且报错，改用字符串模板引擎处理
			if (list.size() > 60000) {
			    response.setContentType("application/octet-stream");
                String fileName = new String((customerCode+"_"+warehouseCode + "_含备注订单.xls").getBytes("GBK"), "ISO8859-1");
                ((HttpServletResponse)response).setHeader("Content-disposition", "attachment; filename=" + fileName);
                
                String[] titles = { "序号", "商家编码","订单号","来源店铺","收货人","目的地","指定快递公司","审单时间","备注"};
                String pageTitle="含备注订单";
                
                
                ExcelStUtil.export(response.getOutputStream(), DateFormatUtils.format(now, "yyyyMMddhhmmss"), pageTitle, titles, list);
			} else {
    			/** 导出数据 */
    			String[] title = { "序号", "商家编码","订单号","来源店铺","收货人","目的地","指定快递公司","审单时间","备注"};
    			String filepath =customerCode+"_"+warehouseCode+"_含备注订单.xls";
    			String title_page="含备注订单";
    			ExcelUtils.writeExcel(title, filepath,title_page, df.format(now) , list); // 生成excel
    			/** 把生成的excel文件读出字节返回给客户端 */
//    			((HttpServletResponse)response).setHeader("Content-disposition", "attachment; filename="+ new String(filepath.getBytes("gb2312"),"utf-8"));
    			((HttpServletResponse)response).setHeader("Content-disposition", "attachment; filename="+ new String(filepath.getBytes("GBK"), "ISO8859-1"));
    			f = new FileInputStream(ExcelUtils.TEMPPATH+filepath);
    			byte[] fb = new byte[f.available()];
    			f.read(fb);
    			ByteArrayInputStream bais = new ByteArrayInputStream(fb);
    			output =((HttpServletResponse)response).getOutputStream();
    			int by = 0;
    			while ((by = bais.read()) != -1) {
    				output.write(by);
    			}
    			output.flush();
			}
			
		} catch (Exception e) {
			log.error("", e);
			return "error";
		}finally{
			if (output!=null) {
				try { output.close(); } catch (IOException e) {log.error("error",e);}
			}
			if (f!=null) {
				try { f.close(); } catch (IOException e)  {log.error("error",e);}
			}
		}
		return null;
	}
    
}